package com.windea.breezeframework.fxgl.extensions.entity

import com.almasb.fxgl.entity.*
import com.almasb.fxgl.entity.component.*
import com.almasb.fxgl.entity.components.*

///////////Query extensions to avoid fake Optional and (a part of) java functional interfaces

fun GameWorld.getSingletonOrNull(type: Enum<*>): Entity? {
	return entities.find { it.isType(type) }
}

fun GameWorld.getSingletonOrNull(predicate: (Entity) -> Boolean): Entity? {
	return entities.find(predicate)
}

@JvmName("getRandom")
fun GameWorld.getRandomOrNull(type: Enum<*>): Entity? {
	return this.getEntitiesByType(type).let { if(it.isEmpty()) null else it.random() }
}

fun GameWorld.getRandom(predicate: (Entity) -> Boolean): Entity? {
	return this.entities.filter { predicate(it) }.let { if(it.isEmpty()) null else it.random() }
}

inline fun <reified T : Component> GameWorld.getEntitiesByComponent(): List<Entity> {
	return entities.filter { it.hasComponent(T::class.java) }
}

fun GameWorld.getClosestEntity(entity: Entity, predicate: (Entity) -> Boolean): Entity? {
	return entities.filter { predicate(it) && it !== entity }.minBy { entity.distance(it) }
}

fun GameWorld.getEntityById(name: String, id: Int): Entity? {
	return getEntitiesByComponent(IDComponent::class.java).find {
		val idComponent = it.getComponent(IDComponent::class.java)
		return@find idComponent.name == name && idComponent.id == id
	}
}
